package org.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

/**
 * @Author：无敌暴龙战士
 * @Package：org.example.config
 * @Project：learn_spring_security
 * @name：MySecurityConfig
 * @Date：2025/2/12 1:45
 * @Filename：MySecurityConfig
 * @Description: 白定义类实现用户详情服务接口
 */
@Configuration
public class MySecurityConfig {
    @Bean
    public UserDetailsService userDetailsService() {
        //创建两个用户
        UserDetails aaa = User.builder().username("aaa").password("123456").roles("student").build();
        UserDetails bbb = User.builder().username("bbb").password("123456").roles("teacher").build();

        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(aaa);
        manager.createUser(bbb);
        return manager;
    }

    /**
     * 定义了一个Spring Security的配置类`MySecurityConfig`，用于配置用户认证信息。通过`@Configuration`注解表明这是一个配置类，并且通过`@Bean`注解定义了一个`UserDetailsService`的Bean。
     * 实现原理
     * 1. 配置类声明：`@Configuration`注解表明这是一个Spring配置类，Spring会自动扫描并加载这个类中的Bean定义。
     * 2. 创建用户信息：通过`User.builder().username("aaa").password("123456").build()`创建两个`UserDetails`对象，分别代表用户`aaa`和`bbb`，密码都是`123456`。
     * 3. 内存用户存储：使用`InMemoryUserDetailsManager`来存储这两个用户信息。`InMemoryUserDetailsManager`是一个内存中的用户存储实现，适合于测试和开发环境。
     * 4. 创建用户：通过`manager.createUser(aaa)`和`manager.createUser(bbb)`将这两个用户添加到`InMemoryUserDetailsManager`中。
     * 5. 返回用户详情服务：最后，将配置好的`InMemoryUserDetailsManager`对象作为`UserDetailsService`的Bean返回。
     * 用途
     * 在Spring Security中配置用户认证信息，通过内存中的用户存储来管理用户信息。这在开发阶段或小型项目中非常实用，因为不需要连接数据库或其他外部存储。
     * 注意事项
     * 1. 安全性：在生产环境中，不建议使用内存存储用户信息，因为这样会导致用户信息丢失。应该使用数据库或其他持久化存储来保存用户信息。
     * 2. 密码加密：在实际应用中，密码不应该以明文形式存储。应该使用密码加密算法（如BCrypt）对密码进行加密处理。
     * 3. 用户角色：这段代码没有配置用户的角色信息。在实际应用中，应该为每个用户分配适当的角色，以便进行权限控制。
     * 4. 配置覆盖：如果项目中已经存在`UserDetailsService`的配置，这段代码中的配置可能会被覆盖。确保没有其他配置类或配置文件覆盖了这段代码的配置。
     */

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    /**
     *这段Java代码是一个Spring框架中的配置代码，用于定义一个名为`passwordEncoder`的Bean。具体来说，它创建了一个`PasswordEncoder`类型的Bean，
     *并返回一个`NoOpPasswordEncoder`的实例。下面是对这段代码的详细解释：
     *实现原理
     *   1. `@Bean`注解：这是Spring框架中的一个注解，用于告诉Spring容器这个方法将返回一个对象，该对象要注册为Spring应用上下文中的Bean。Spring容器会管理这个Bean的生命周期，包括创建、初始化、销毁等。
     *   2. `PasswordEncoder`接口：这是Spring Security框架中的一个接口，用于定义密码编码（加密）的规范。实现这个接口的类负责将用户输入的密码进行编码，以便存储在数据库中。
     *   3. `NoOpPasswordEncoder`类：这是Spring Security框架中的一个类，实现了`PasswordEncoder`接口。`NoOpPasswordEncoder`类提供了一个“不操作”的密码编码器，即它不对密码进行任何编码，
     *直接返回原始密码。这在某些测试环境中或者开发环境中可能会用到，但在生产环境中使用是不安全的，因为它没有对密码进行加密。
     *用途
     *在Spring应用中配置一个密码编码器，用于对用户密码进行编码。通过配置这个Bean，Spring Security会使用这个密码编码器来处理密码的编码和解码。
     *这段代码将使用`BCryptPasswordEncoder`来对密码进行编码，这是一种常用的、安全的密码编码方式。
     *@Bean
     *public PasswordEncoder passwordEncoder() {
     *    return new BCryptPasswordEncoder();
     *}
     */


}


